Using ASP to loop thru XML file and generate HTML
am 30.11.2007 01:27:56 von otherblandart
Hi All and thanks in advance for any help I can get with this!
I'm very new at ASP/XML/HTML, but pretty comfortable with VB/
VBScript.
I've been tasked with some web content development tasks, and among
them is a 'catalog' style page of images. Rather than hard-coding all
the items, I wanted to use an XML file to store all the image paths
and descriptive text, and just loop thru it to generate the HTML I
need. Later on I'll be adding things like filters on category, etc.,
but for now I just want to get a simple protoype working. Below is
what I've come up with but it just isn't working (keep getting HTTP
500 Internal Server Error with IE 6).
The objects/methods worked pretty well in VB, so I'm wondering if
it's
in my handling of the quotation marks...
Thanks again for the help!
Hal
[XML File]
images/success_do.jpg
"Success Means Do.." Poster 24X16
images/Think_Twice.jpg
"Think Twice.. Act Once" Poster 18X36
[ASP Page Text]
<%
dim strServer
dim objXML, xNodeList, xNode
dim i , s, sDesc, sPath
strServer = Request.ServerVariables("SERVER_NAME")
%>
Order Framed Art
<%
set objXML = Server.CreateObject("Microsoft.XMLDOM")
sPath = "http://" & strServer & "/vendor_mgmt/docs/artlist.xml"
objXML.async = False
objXML.load(sPath)
If objXML.parseError.errorcode <> 0 then
Response.Write "Sorry, an error occurred retrieving information."
else
Set xNodeList =
objXML.documentElement.getElementsByTagName("item")
If xNodeList.length > 0 then
For i=0 to xNodeList.length-1
'[imgpath] element/field
sPath = "http://" & strServer & "/vendor_mgmt/" &
xNodelist.Item(i).childNodes(0).text
'[described] element/field
sDesc = xNodelist.Item(i).childNodes(1).text
s = ""
Response.Write s
s = "
s = s & " height=" & Chr(34) & "50" & Chr(34) & " align="
& Chr(34) & "middle" & Chr(34) & ">
"
Response.Write s
s = "" & i & ". "
s = s & sDesc & ""
Response.Write s
next
else
'no items exist
end if
end if
%>
Re: Using ASP to loop thru XML file and generate HTML
am 01.12.2007 19:58:50 von Anthony Jones
wrote in message
news:cebc09f1-5053-4e09-b82c-cb040de5b819@l1g2000hsa.googleg roups.com...
> Hi All and thanks in advance for any help I can get with this!
>
> I'm very new at ASP/XML/HTML, but pretty comfortable with VB/
> VBScript.
>
>
> I've been tasked with some web content development tasks, and among
> them is a 'catalog' style page of images. Rather than hard-coding all
> the items, I wanted to use an XML file to store all the image paths
> and descriptive text, and just loop thru it to generate the HTML I
> need. Later on I'll be adding things like filters on category, etc.,
> but for now I just want to get a simple protoype working. Below is
> what I've come up with but it just isn't working (keep getting HTTP
> 500 Internal Server Error with IE 6).
>
>
> The objects/methods worked pretty well in VB, so I'm wondering if
> it's
> in my handling of the quotation marks...
>
>
For some reason I feel the need to write a complete article on this so here
it is:-
>
>
> [XML File]
>
>
>
>
>
> images/success_do.jpg
> "Success Means Do.." Poster 24X16
>
>
> images/Think_Twice.jpg
> "Think Twice.. Act Once" Poster 18X36
>
>
>
I did have some comments on the XML here but I've removed them for the
moment. I will add a second post which will look at an alternative XML and
the use of XSL which may be more appropriate as you move forward. For now
though I'll consider some of the issues with the ASP/
Don't make any adjustments to your code because later I'll give you a
complete working sample.
>
> [ASP Page Text]
>
>
>
> <%
> dim strServer
> dim objXML, xNodeList, xNode
> dim i , s, sDesc, sPath
> strServer = Request.ServerVariables("SERVER_NAME")
> %>
It would be better to place variables closer to the code itself. I usually
prefer to put as much code in the top of the page above the element.
That keeps the code and HTML as separate as possible. You would still need
some code in <% %> interspersed in the HTML to effect loops and output
values etc but the idea is to keep that sort of thing to a minimum.
>
>
>
>
>
>
>
Frontpage has probably added these, I wouldn't include any of them. I would
especially avoid http-equiv. In ASP you have the ability to set the actual
http headers. In this case all you really need is to specify the char set
you are using:-
Response.CharSet = "Window-1252"
> Order Framed Art
>
>
> <%
> set objXML = Server.CreateObject("Microsoft.XMLDOM")
Always use a version specific ProgID to create an XML DOM. I normally use
MSXML2.DOMDocument.3.0 because you can pretty certain that that is installed
on all servers.
If you want the latest DOM install MSXML6 and use MSXML2.DOMDocument.6.0.
Don't use 4.0 or 5.0.
> sPath = "http://" & strServer & "/vendor_mgmt/docs/artlist.xml"
There is no need to try to fetch XML via HTTP when your code is running in
an application on the server that it resides in. The following would be a
better way to set sPath:-
sPath = Server.MapPath("/vendor_mgmt/docs/artlist.xml")
Now sPath contains the on disk physical file path that the XML DOM can load.
> objXML.async = False
> objXML.load(sPath)
Note that calling procedures when you aren't using a return value in
VBScript is done without parantheses. E.g.:-
objXML.load sPath
>
>
> If objXML.parseError.errorcode <> 0 then
> Response.Write "Sorry, an error occurred retrieving information."
When asserting that conditions are ok to continue in this way it is
acceptable to use Response.End(). Hence you could follow the above with:-
Response.End()
End If
The main body of your code doesn't therefore start off indented and doesn't
leave a reader of the code wondering what the additonal End If at the bottom
of the code is doing. BTW, from a code construction point of view its
better that the "Then" protion of an If Then Else EndIf construct contain
the nominal path of the code and the "Else" portion contain the exceptional
portion of code.
> else
> Set xNodeList =
> objXML.documentElement.getElementsByTagName("item")
A problem with using getElementsByTabName is that it will return all
descendant elements with the specified tag name not just the direct
children. If at a later time you added a deeper hierarchy which just
happens to use a tagName of "item" for a different purpose then the method
above would include those elements as well. Better:-
Set oNodeList = objXML.documentElement.selectNodes("item")
That selects only child item elements.
> If xNodeList.length > 0 then
This test is unnecessary at this point since the following For loop does
nothing if length is 0 anyway.
> For i=0 to xNodeList.length-1
A better way to loop through a list of nodes is to use the For Each
construct:-
For Each oNode In oNodeList
You could then replace all use of xNodelist.Item(i) with simply oNode. This
would be quicker (you only retrieve the node reference once) and simpler.
> '[imgpath] element/field
> sPath = "http://" & strServer & "/vendor_mgmt/" &
> xNodelist.Item(i).childNodes(0).text
There is no need to prefix the /vendor_mgmt/ path with the protocol or
server name. The browser will assume those to be the same as the current
page.
..childNodes(0) is retrieving the imgpath element on the assumption that it
is the first child element of item. That may not always be true. I use
this sort of function for this purpose:-
Function GetNodeText(roParent, rsPath, rsDef)
Dim oNode : Set oNode = roParent.selectSingleNode(rsPath)
If Not oNode Is Nothing Then
GetNodeText = oNode.text
Else
GetNodeText = rsDef
End If
End Function
Hence the line becomes:-
sPath = "/vendor_mgmt/" & GetNodeText(oNode, "imgpath",
"images/noimageavail.jpg")
> '[described] element/field
> sDesc = xNodelist.Item(i).childNodes(1).text
What happens if sDesc contains a character that has special meaning in HTML
such as & or <
The output will be broken such characters need to be encoded correctly.
This is done with the Server.HTMLEncode :-
sDesc = Server.HTMLEncode(GetNodeText(oNode, "described", "No description"))
> s = ""
> Response.Write s
I suppose it may be a matter of preference but I think using "" in a string
as an escaped " is better than using a separate concatenation of & Chr(34)
&; if you look at the code closely you can see a syntax error which is easy
to do with so much contatenation.
Response.Write "
target=""_blank"">"
> s = "
> s = s & " height=" & Chr(34) & "50" & Chr(34) & " align="
> & Chr(34) & "middle" & Chr(34) & ">
"
> Response.Write s
Now this it getting really ugly primarily down to the Chr(34) as I've
mentioned but also the use of the deprecated style attributes isn't helping.
Attributes such as border, width, height and align should now be applied
using the style attribute which takes the corresponding CSS attributes
border, width, height and vertical-align. Further since these are common to
a whole set of imgs it would be better to place the style in a selector in
an inpage CSS style element.
In the of the page you could do this:-
Now the code above becomes:-
Response.Write ""
> s = "" & i & ". "
> s = s & sDesc & ""
> Response.Write s
If you got your code working I think you will be disappointed with the
layout of the result. I think the
previously output is in the wrong
place, I suspect you wanted the img followed by the text then the break.
Since img and the text are adjacent to each other there really isn't any
need for multiple , just one the covers both image and text would be
sufficient.
Now having said all that the it worth noting that only three things vary per
loop sDesc, sPath and i. Yet most of the code is involved in pasting
strings together and writing them to the response. This a case where a HTML
block would be better:-
i = 0
For Each oNode In oNodeList
sPath = "/vendor_mgmt/" & GetNodeText(oNode, "imgpath",
"images/noimageavail.jpg")
sDesc = Server.HTMLEncode(GetNodeText(oNode, "described", "No
description"))
i = i + 1
%>
<%
Next
The above code is shorter, faster, more robust and easier to understand.
> next
> else
> 'no items exist
> end if
Its here you might just want to test If oNodeList.length = 0 and output some
HTML to indicate no items were found.
> end if
> %>
>
>
Putting it all together then we get:-
<%
Dim i, sPath, sDesc
Dim oXML, oNodeList, oNode
Response.CharSet = "Window-1252"
Set oXML = Server.CreateObject("MSXML2.DOMDocument.3.0")
oXML.async = False
oXML.Load Server.MapPath("test.xml")
If oXML.parseError.errorCode <> 0 Then
Err.Raise 1001, "Loading DOM", oXML.parseError.reason
Response.End()
End If
%>
<%
Set oNodeList = oXML.documentElement.selectNodes("item")
i = 0
For Each oNode In oNodeList
sPath = "/vendor_mgmt/" & GetNodeText(oNode, "imgpath",
"images/noimageavail.jpg")
sDesc = Server.HTMLEncode(GetNodeText(oNode, "described", "No
description"))
i = i + 1
%>
<%
Next
If oNodeList.length = 0 Then
%>
No items found
<%
End If
%>
<%
Function GetNodeText(roParent, rsPath, rsDef)
Dim oNode : Set oNode = roParent.selectSingleNode(rsPath)
If Not oNode Is Nothing Then
GetNodeText = oNode.text
Else
GetNodeText = rsDef
End If
End Function
%>
Hope you find this helpful. I'll make another posting later which will look
at the structure of the XML and using XSL to generate the output.
--
Anthony Jones - MVP ASP/ASP.NET
Re: Using ASP to loop thru XML file and generate HTML
am 03.12.2007 21:08:06 von otherblandart
Anthony,
Thanks for the help, I'd been going off of syntax I found elsewhere on
the web, so I appreciate the shortcuts to make it easier to read/code.
I wasn't able to get it to work with server scripting (<%%>), but once
I wrapped it in a VBScript ). Some syntactical
changes were required, but it's working more or less the way I want it
to now. Not sure why I had to go that route, but apparently my
employer does some weird things with the settings on their web
servers, so it's anybody's guess.
Thanks again!
H
Re: Using ASP to loop thru XML file and generate HTML
am 03.12.2007 23:12:32 von Anthony Jones
wrote in message
news:d81ce433-e4a0-41b0-93ea-65ad3688ccc6@x69g2000hsx.google groups.com...
> Anthony,
>
> Thanks for the help. Most of the syntax I'd posted I'd followed from
> instructions I'd found elsewhere on the web, the tips for making it
> easier to read/code are greatly appreciated!
>
> For some reason I couldn't get the syntax to work as laid out in your
> reply, but had some success when I tried switching from asp scripting
> (<%-%>) to using VBScript (). Some syntactical
> changes were required, but it's working more or less the way I want it
> to now. Not sure why I had to go that route, but apparently my
> employer does some weird things with the settings on their web
> servers, so it's anybody's guess.
>
Probably because the default language is set to something other that
VBScript. Most like JScript (which given the choice would be my preference
as well).
--
Anthony Jones - MVP ASP/ASP.NET